// ----------------------------------
// RSDK Project: Sonic 2
// Script Description: ARZ Setup Object
// Script Author: Christian Whitehead/Simon Thomley
// Unpacked by Rubberduckycooly's script unpacker
// ----------------------------------

// ========================
// Aliases
// ========================

private alias object.value6  : object.clrDivisor_R
private alias object.value7  : object.clrDivisor_G
private alias object.value8  : object.clrDivisor_B
private alias object.value9  : object.waterClrDivisor_R
private alias object.value10 : object.waterClrDivisor_G
private alias object.value11 : object.waterClrDivisor_B

private alias object.value1  : object.paletteTimer

// Tracks
private alias 0 : TRACK_STAGE
private alias 1 : TRACK_ACTFINISH
private alias 2 : TRACK_INVINCIBLE
private alias 3 : TRACK_CONTINUE
private alias 4 : TRACK_BOSS
private alias 5 : TRACK_GAMEOVER
private alias 6 : TRACK_DROWNING
private alias 7 : TRACK_SUPER

// Reserved object slots
private alias 10 : SLOT_ZONESETUP
private alias 25 : SLOT_MUSICEVENT_CHANGE
private alias 26 : SLOT_MUSICEVENT_BOSS

// Music Events
private alias 2 : MUSICEVENT_TRANSITION

private alias 0 : MUSICEVENT_FLAG_NOCHANGE
private alias 1 : MUSICEVENT_FLAG_SPEEDUP
private alias 2 : MUSICEVENT_FLAG_SLOWDOWN

// Music Loops
private alias 1     : MUSIC_LOOP_ARZ
private alias 1     : MUSIC_LOOP_ARZ_F

private alias 38679 : MUSIC_LOOP_INV
private alias 30897 : MUSIC_LOOP_INV_F


// ========================
// Function Declarations
// ========================

reserve function ARZSetup_getClrDivisor
reserve function ARZSetup_InitSuperSonicPal
reserve function ARZSetup_InitSuperTailsPal
reserve function ARZSetup_InitSuperKnuxPal
reserve function ARZSetup_InitSuperAmyPal
reserve function ARZSetup_SpeedUpMusic
reserve function ARZSetup_SlowDownMusic


// ========================
// Static Values
// ========================

public value Water_flashTimer = 0 // Uses "Water_" since all water objects use it from the setup so its easier to make new objs this way


// ========================
// Tables
// ========================

private table ARZSetup_replay_attract_S
	0x6C0000, 0x37D0000
	0x00, 68
	0x08, 68
	0x38, 1
	0x28, 4
	0x08, 6
	0x00, 26
	0x08, 37
	0x00, 2
	0x08, 13
	0x00, 28
	0x30, 1
	0x20, 10
	0x24, 3
	0x20, 15
	0x28, 5
	0x08, 34
	0x38, 1
	0x28, 5
	0x08, 170
	0x00, 2
	0x02, 8
	0x06, 1
	0x04, 15
	0x00, 18
	0x08, 81
	0x00, 53
	0x30, 1
	0x20, 6
	0x24, 23
	0x00, 57
	0x08, 52
	0x38, 1
	0x28, 2
	0x08, 43
	0x00, 76
	0x30, 1
	0x20, 17
	0x28, 39
	0x08, 32
	0x0A, 2
	0x02, 15
	0x00, 35
	0x30, 1
	0x20, 45
	0x00, 33
	0x30, 1
	0x20, 52
	0x24, 3
	0x04, 25
	0x00, 5
	0x30, 1
	0x20, 1
	0x28, 96
	0x20, 1
	0x24, 2
	0x04, 13
	0x00, 27
	0x08, 7
	0x38, 1
	0x28, 22
	0x08, 11
	0x00, 1
	0x04, 10
	0x00, 10
	0x08, 85
	0x00, 8
	0x08, 11
	0x38, 1
	0x28, 4
	0x08, 23
	0x00, 66
	0x08, 5
	0x38, 1
	0x28, 19
	0x08, 84
	0x38, 1
end table


private table ARZSetup_replay_attract_T
	0x6C0000, 0x3810000
	0x00, 18
	0x08, 63
	0x38, 1
	0x28, 5
	0x08, 85
	0x38, 1
	0x28, 1
	0x20, 16
	0x28, 7
	0x08, 175
	0x38, 1
	0x28, 48
	0x08, 15
	0x38, 1
	0x28, 45
	0x08, 97
	0x0A, 3
	0x02, 39
	0x00, 4
	0x08, 108
	0x38, 1
	0x28, 46
	0x08, 199
	0x38, 1
	0x28, 59
	0x08, 3
	0x0A, 4
	0x02, 4
	0x0A, 11
	0x08, 2
	0x00, 1
	0x02, 28
	0x08, 214
	0x0A, 2
	0x02, 77
	0x00, 1
	0x04, 20
	0x00, 65
	0x08, 22
	0x38, 1
	0x28, 2
	0x08, 161
	0x38, 1
	0x28, 12
	0x08, 43
	0x38, 1
	0x28, 8
	0x08, 8
	0x38, 1
	0x28, 7
	0x08, 4
	0x38, 1
	0x28, 4
	0x08, 4
	0x38, 1
	0x28, 6
	0x08, 3
	0x38, 1
	0x28, 6
	0x08, 3
	0x38, 1
	0x28, 6
	0x08, 3
	0x38, 1
	0x28, 6
	0x08, 3
	0x38, 1
	0x28, 5
end table


private table ARZSetup_replay_attract_K
	0x6C0000, 0x37D0000
	0x00, 50
	0x08, 66
	0x38, 1
	0x28, 5
	0x08, 86
	0x38, 1
	0x28, 6
	0x08, 216
	0x38, 1
	0x28, 14
	0x08, 23
	0x38, 1
	0x28, 18
	0x08, 116
	0x0A, 2
	0x02, 5
	0x00, 3
	0x08, 144
	0x38, 1
	0x28, 23
	0x08, 5
	0x38, 1
	0x28, 127
	0x00, 11
	0x02, 13
	0x32, 1
	0x22, 3
	0x00, 5
	0x08, 96
	0x0A, 1
	0x02, 8
	0x0A, 2
	0x08, 159
	0x38, 1
	0x28, 18
	0x08, 5
	0x38, 1
	0x28, 57
	0x08, 1
	0x00, 10
	0x02, 17
	0x32, 1
	0x22, 3
	0x00, 6
	0x08, 40
	0x00, 19
	0x08, 27
	0x38, 1
	0x28, 11
	0x08, 6
	0x38, 1
	0x28, 66
	0x29, 6
	0x21, 14
	0x01, 22
	0x00, 107
	0x01, 51
	0x00, 6
	0x02, 6
	0x32, 1
	0x22, 2
	0x00, 1
end table


// ========================
// Function Definitions
// ========================

private function ARZSetup_getClrDivisor
	object.clrDivisor_R = temp1
	object.clrDivisor_R >>= 16
	
	object.clrDivisor_G = temp1
	object.clrDivisor_G >>= 8
	object.clrDivisor_G &= 0xFF

	object.clrDivisor_B = temp1
	object.clrDivisor_B &= 0xFF

	object.waterClrDivisor_R = temp2
	object.waterClrDivisor_R >>= 16

	object.waterClrDivisor_G = temp2
	object.waterClrDivisor_G >>= 8
	object.waterClrDivisor_G &= 0xFF

	object.waterClrDivisor_B = temp2
	object.waterClrDivisor_B &= 0xFF

	if object.waterClrDivisor_R == 0
		object.waterClrDivisor_R = 1
	end if

	if object.waterClrDivisor_G == 0
		object.waterClrDivisor_G = 1
	end if

	if object.waterClrDivisor_B == 0
		object.waterClrDivisor_B = 1
	end if

	object.clrDivisor_R <<= 8
	object.clrDivisor_G <<= 8
	object.clrDivisor_B <<= 8
	object.clrDivisor_R /= object.waterClrDivisor_R
	object.clrDivisor_G /= object.waterClrDivisor_G
	object.clrDivisor_B /= object.waterClrDivisor_B

	if object.clrDivisor_R == 0
		object.clrDivisor_R = 0x100
	end if

	if object.clrDivisor_G == 0
		object.clrDivisor_G = 0x100
	end if

	if object.clrDivisor_B == 0
		object.clrDivisor_B = 0x100
	end if
end function


private function ARZSetup_InitSuperSonicPal
	temp0 = 0

	GetPaletteEntry(1, 2, temp1)
	SetTableValue(temp1, temp0, Player_SonicSuperAltPal)
	temp0++

	GetPaletteEntry(1, 3, temp1)
	SetTableValue(temp1, temp0, Player_SonicSuperAltPal)
	temp0++

	GetPaletteEntry(1, 4, temp1)
	SetTableValue(temp1, temp0, Player_SonicSuperAltPal)
	temp0++

	GetPaletteEntry(1, 5, temp1)
	SetTableValue(temp1, temp0, Player_SonicSuperAltPal)
	temp0++

	while temp0 < 64
		GetPaletteEntry(0, 2, temp1)
		GetPaletteEntry(1, 2, temp2)

		CallFunction(ARZSetup_getClrDivisor)

		GetTableValue(temp1, temp0, Player_SonicSuperPal)

		temp2 = temp1
		temp2 >>= 8
		temp2 &= 0xFF

		temp3 = temp1
		temp3 &= 0xFF

		temp1 >>= 16

		temp1 *= 0xE0
		temp1 /= object.clrDivisor_R

		temp2 *= 0xE0
		temp2 /= object.clrDivisor_G

		temp3 *= 0xE0
		temp3 /= object.clrDivisor_B

		temp1 &= 0xF0
		temp2 &= 0xF0
		temp3 &= 0xF0

		if temp1 > 0xE0
			temp1 = 0xE0
		end if

		if temp2 > 0xE0
			temp2 = 0xE0
		end if

		if temp3 > 0xE0
			temp3 = 0xE0
		end if

		temp1 <<= 16
		temp2 <<= 8
		temp1 += temp2
		temp1 += temp3
		SetTableValue(temp1, temp0, Player_SonicSuperAltPal)
		temp0++

		GetPaletteEntry(0, 3, temp1)
		GetPaletteEntry(1, 3, temp2)

		CallFunction(ARZSetup_getClrDivisor)

		GetTableValue(temp1, temp0, Player_SonicSuperPal)

		temp2 = temp1
		temp2 >>= 8
		temp2 &= 0xFF

		temp3 = temp1
		temp3 &= 0xFF

		temp1 >>= 16

		temp1 *= 0xE8
		temp1 /= object.clrDivisor_R

		temp2 *= 0xE8
		temp2 /= object.clrDivisor_G

		temp3 *= 0xE8
		temp3 /= object.clrDivisor_B

		temp1 &= 0xF0
		temp2 &= 0xF0
		temp3 &= 0xF0

		if temp1 > 0xE0
			temp1 = 0xE0
		end if

		if temp2 > 0xE0
			temp2 = 0xE0
		end if

		if temp3 > 0xE0
			temp3 = 0xE0
		end if

		temp1 <<= 16
		temp2 <<= 8
		temp1 += temp2
		temp1 += temp3
		SetTableValue(temp1, temp0, Player_SonicSuperAltPal)
		temp0++

		GetPaletteEntry(0, 4, temp1)
		GetPaletteEntry(1, 4, temp2)

		CallFunction(ARZSetup_getClrDivisor)

		GetTableValue(temp1, temp0, Player_SonicSuperPal)

		temp2 = temp1
		temp2 >>= 8
		temp2 &= 0xFF

		temp3 = temp1
		temp3 &= 0xFF

		temp1 >>= 16

		temp1 *= 0xF4
		temp1 /= object.clrDivisor_R

		temp2 *= 0xF4
		temp2 /= object.clrDivisor_G

		temp3 *= 0xF4
		temp3 /= object.clrDivisor_B

		temp1 &= 0xF0
		temp2 &= 0xF0
		temp3 &= 0xF0

		if temp1 > 0xE0
			temp1 = 0xE0
		end if

		if temp2 > 0xE0
			temp2 = 0xE0
		end if

		if temp3 > 0xE0
			temp3 = 0xE0
		end if

		temp1 <<= 16
		temp2 <<= 8
		temp1 += temp2
		temp1 += temp3
		SetTableValue(temp1, temp0, Player_SonicSuperAltPal)
		temp0++

		GetPaletteEntry(0, 5, temp1)
		GetPaletteEntry(1, 5, temp2)

		CallFunction(ARZSetup_getClrDivisor)

		GetTableValue(temp1, temp0, Player_SonicSuperPal)

		temp2 = temp1
		temp2 >>= 8
		temp2 &= 0xFF

		temp3 = temp1
		temp3 &= 0xFF

		temp1 >>= 16

		temp1 *= 0x100
		temp1 /= object.clrDivisor_R

		temp2 *= 0x100
		temp2 /= object.clrDivisor_G

		temp3 *= 0x100
		temp3 /= object.clrDivisor_B

		temp1 &= 0xF0
		temp2 &= 0xF0
		temp3 &= 0xF0

		if temp1 > 0xE0
			temp1 = 0xE0
		end if

		if temp2 > 0xE0
			temp2 = 0xE0
		end if

		if temp3 > 0xE0
			temp3 = 0xE0
		end if

		temp1 <<= 16
		temp2 <<= 8
		temp1 += temp2
		temp1 += temp3
		SetTableValue(temp1, temp0, Player_SonicSuperAltPal)
		temp0++
	loop
end function


private function ARZSetup_InitSuperTailsPal
	temp0 = 0
	GetPaletteEntry(1, 54, temp1)
	SetTableValue(temp1, temp0, Player_TailsSuperAltPal)
	temp0++

	GetPaletteEntry(1, 53, temp1)
	SetTableValue(temp1, temp0, Player_TailsSuperAltPal)
	temp0++
	
	GetPaletteEntry(1, 51, temp1)
	SetTableValue(temp1, temp0, Player_TailsSuperAltPal)
	temp0++

	GetPaletteEntry(1, 50, temp1)
	SetTableValue(temp1, temp0, Player_TailsSuperAltPal)
	temp0++
end function


private function ARZSetup_InitSuperKnuxPal
	temp0 = 0
	
	GetPaletteEntry(1, 26, temp1)
	SetTableValue(temp1, temp0, Player_KnuxSuperAltPal)
	temp0++

	GetPaletteEntry(1, 27, temp1)
	SetTableValue(temp1, temp0, Player_KnuxSuperAltPal)
	temp0++

	GetPaletteEntry(1, 28, temp1)
	SetTableValue(temp1, temp0, Player_KnuxSuperAltPal)
	temp0++
end function


private function ARZSetup_InitSuperAmyPal
#platform: USE_ORIGINS
	temp0 = 0
	
	GetPaletteEntry(1, 54, temp1)
	SetTableValue(temp1, temp0, Player_AmySuperAltPal)
	temp0++
	
	GetPaletteEntry(1, 50, temp1)
	SetTableValue(temp1, temp0, Player_AmySuperAltPal)
	temp0++
	
	GetPaletteEntry(1, 51, temp1)
	SetTableValue(temp1, temp0, Player_AmySuperAltPal)
	temp0++
	
	GetPaletteEntry(1, 52, temp1)
	SetTableValue(temp1, temp0, Player_AmySuperAltPal)
	temp0++
	
	GetPaletteEntry(1, 53, temp1)
	SetTableValue(temp1, temp0, Player_AmySuperAltPal)
	temp0++
	
	while temp0 < 30
		temp4 = temp0
		temp4 -= 5
		
		GetTableValue(temp1, temp4, Player_AmySuperAltPal)
		
		temp2 = temp1
		temp2 >>= 8
		temp2 &= 255
		
		temp3 = temp1
		temp3 &= 255
		
		temp1 >>= 16
		temp1 += 32
		if temp1 > 255
			temp1 = 255
		end if
		
		temp2 += 32
		if temp2 > 255
			temp2 = 255
		end if
		
		temp3 += 32
		if temp3 > 255
			temp3 = 255
		end if
		
		temp1 <<= 16
		temp2 <<= 8
		temp1 += temp2
		temp1 += temp3
		SetTableValue(temp1, temp0, Player_AmySuperAltPal)
		temp0++
	loop
	
	temp6 = 25
	while temp0 < 50
		temp5 = 0
		while temp5 < 5
			temp4 = temp6
			temp4 += temp5
			GetTableValue(temp1, temp4, Player_AmySuperAltPal)
			SetTableValue(temp1, temp0, Player_AmySuperAltPal)
			temp0++
			temp5++
		loop
		
		temp6 -= 5
	loop
#endplatform
end function


private function ARZSetup_SpeedUpMusic
	CheckEqual(object[SLOT_MUSICEVENT_CHANGE].type, TypeName[Music Event])
	temp0 = checkResult
	CheckEqual(object[SLOT_MUSICEVENT_CHANGE].propertyValue, MUSICEVENT_TRANSITION)
	temp0 &= checkResult
	CheckEqual(stage.musicFlag, MUSICEVENT_FLAG_NOCHANGE)
	temp0 &= checkResult
	if temp0 == false
		switch music.currentTrack
		case TRACK_STAGE
			SetMusicTrack("Invincibility_F.ogg", TRACK_INVINCIBLE, MUSIC_LOOP_INV_F)
			SwapMusicTrack("AquaticRuin_F.ogg", TRACK_STAGE, MUSIC_LOOP_ARZ_F, 8000)
			break

		case TRACK_INVINCIBLE
			SetMusicTrack("AquaticRuin_F.ogg", TRACK_STAGE, MUSIC_LOOP_ARZ_F)
			SwapMusicTrack("Invincibility_F.ogg", TRACK_INVINCIBLE, MUSIC_LOOP_INV_F, 8000)
			break

		case TRACK_BOSS
		case TRACK_DROWNING
		case TRACK_SUPER
			SetMusicTrack("AquaticRuin_F.ogg", TRACK_STAGE, MUSIC_LOOP_ARZ_F)
			SetMusicTrack("Invincibility_F.ogg", TRACK_INVINCIBLE, MUSIC_LOOP_INV_F)
			break
		end switch
	else
		stage.musicFlag = MUSICEVENT_FLAG_SPEEDUP
	end if
end function


private function ARZSetup_SlowDownMusic
	CheckEqual(object[SLOT_MUSICEVENT_CHANGE].type, TypeName[Music Event])
	temp0 = checkResult
	CheckEqual(object[SLOT_MUSICEVENT_CHANGE].propertyValue, MUSICEVENT_TRANSITION)
	temp0 &= checkResult
	CheckEqual(stage.musicFlag, MUSICEVENT_FLAG_NOCHANGE)
	temp0 &= checkResult
	if temp0 == false
		switch music.currentTrack
		case TRACK_STAGE
			SetMusicTrack("Invincibility.ogg", TRACK_INVINCIBLE, MUSIC_LOOP_INV)
			SwapMusicTrack("AquaticRuin.ogg", TRACK_STAGE, MUSIC_LOOP_ARZ, 12500)
			break

		case TRACK_INVINCIBLE
			SetMusicTrack("AquaticRuin.ogg", TRACK_STAGE, MUSIC_LOOP_ARZ)
			SwapMusicTrack("Invincibility.ogg", TRACK_INVINCIBLE, MUSIC_LOOP_INV, 12500)
			break

		case TRACK_BOSS
		case TRACK_DROWNING
		case TRACK_SUPER
			SetMusicTrack("AquaticRuin.ogg", TRACK_STAGE, MUSIC_LOOP_ARZ)
			SetMusicTrack("Invincibility.ogg", TRACK_INVINCIBLE, MUSIC_LOOP_INV)
			break
		end switch
	else
		stage.musicFlag = MUSICEVENT_FLAG_SLOWDOWN
	end if
end function


// ========================
// Events
// ========================

event ObjectUpdate
	object.paletteTimer++
	if object.paletteTimer == 6
		// Animate the waterfalls
		object.paletteTimer = 0
		RotatePalette(0, 162, 165, true)
		RotatePalette(1, 162, 165, true)
	end if

	if Water_flashTimer > 0
		Water_flashTimer--
	end if
end event


event ObjectDraw
	temp0 = stage.waterLevel
	temp0 -= screen.yoffset
	if temp0 < 0
		temp0 = 0
	end if
	if temp0 > screen.ysize
		temp0 = screen.ysize
	end if

	SetActivePalette(0, 0, temp0)
	if Water_flashTimer > 0
		SetActivePalette(2, temp0, screen.ysize)
	else
		SetActivePalette(1, temp0, screen.ysize)
	end if
end event


event ObjectStartup
	// Set the stage layer midpoint but, this is already what's present in the scene file?
	// So why is it set again here..?
	stage.midPoint = 2
	
	// Reset the boss flash color to be pure black
	SetPaletteEntry(0, 192, 0x000000)

	SetMusicTrack("AquaticRuin.ogg", TRACK_STAGE, MUSIC_LOOP_ARZ)

	SpeedUpMusic = ARZSetup_SpeedUpMusic
	SlowDownMusic = ARZSetup_SlowDownMusic

	animalType1 = TypeName[Flicky]
	animalType2 = TypeName[Pecky]

	object[SLOT_ZONESETUP].type = TypeName[ARZ Setup]
	object[SLOT_ZONESETUP].priority = PRIORITY_ACTIVE
	object[SLOT_ZONESETUP].drawOrder = 0

	// Different BG properties for the different acts
	// -> Boss attack isn't listed here, so it uses the default values already in the scene file
	switch stage.actNum
	case 1
		stage.curYBoundary1 = 512
		tileLayer[1].scrollPos = -0x1800000
		tileLayer[2].scrollPos = -0x1800000
		tileLayer[1].parallaxFactor = 0x100
		tileLayer[2].parallaxFactor = 0x100
			break
			
		case 2
		stage.curYBoundary1 = 384
		tileLayer[3].scrollPos = -0x800000
		tileLayer[4].scrollPos = -0x800000
		tileLayer[3].parallaxFactor = 0x80
		tileLayer[4].parallaxFactor = 0x80
		break
	end switch

	LoadPalette("ARZ_WaterPal.act", 1, 0, 0, 256)

	CallFunction(ARZSetup_InitSuperSonicPal)
	CallFunction(ARZSetup_InitSuperTailsPal)
	CallFunction(ARZSetup_InitSuperKnuxPal)
#platform: USE_ORIGINS
	CallFunction(ARZSetup_InitSuperAmyPal)
#endplatform

	LoadPalette("ElectricFlash.act", 2, 0, 0, 256)
	Water_flashTimer = 0

	if options.attractMode == true
		switch stage.playerListPos
		case PLAYER_SONIC_A
#platform: USE_ORIGINS
		case PLAYER_AMY_A // Amy isn't even able to show up in demos, but check for her anyway I guess
#endplatform
			Player_attractTable = ARZSetup_replay_attract_S
			Player_attractTableSize = 154
			Player_attractDuration = 1740
			break
			
		case PLAYER_TAILS_A
			Player_attractTable = ARZSetup_replay_attract_T
			Player_attractTableSize = 138
			Player_attractDuration = 1800
			break
			
		case PLAYER_KNUCKLES_A
			Player_attractTable = ARZSetup_replay_attract_K
			Player_attractTableSize = 126
			Player_attractDuration = 1800
			break
		end switch
		
		CallFunction(Player_SetupAttractDemo)
	end if
end event


// ========================
// Editor Events
// ========================

event RSDKDraw
	DrawSprite(0)
end event


event RSDKLoad
	LoadSpriteSheet("Global/Display.gif")
	SpriteFrame(-16, -16, 32, 32, 1, 143)
	
	SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
end event
